package com.bdbit.ChargingStation.services;

import com.bdbit.ChargingStation.entity.OrderEntity;
import com.bdbit.ChargingStation.Enum.OrderStatus;
import com.alibaba.fastjson.JSONObject;
import com.bdbit.ChargingStation.controller.ChargingOrderController;
import com.bdbit.ChargingStation.services.impl.ChargingOrderServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;

@Slf4j
@Component
public class MqttMessageListener {

    @Autowired
    private DeviceOrderService deviceOrderService;

    @Autowired
    private SimpleChargingRetryService simpleChargingRetryService;

    @Autowired
    private ChargingOrderService chargingOrderService;

    @Autowired
    private ChargingOrderController chargingOrderController;

    @Autowired
    private PaymentService paymentService;

    // 手动处理消息
    // handlePowerOutageEvent方法 (第31行)
    public void handlePowerOutageEvent(String message) {
        JSONObject payload = JSONObject.parseObject(message);
        String eleCode = payload.getString("device_id");

        String orderId = deviceOrderService.getOrderIdByDeviceUnified(eleCode);

        if (orderId != null) {
            JSONObject request = new JSONObject();
            request.put("order_id", orderId);
            request.put("id", orderId);
            request.put("ele_code", eleCode);
            chargingOrderController.handlePowerOutage(request);
        } else {
            log.warn("收到断电事件但未找到关联订单: eleCode={}", eleCode);
        }
    }

    // handleChargingComplete方法 (第47行)
    public void handleChargingComplete(String message) {
        JSONObject payload = JSONObject.parseObject(message);
        String eleCode = payload.getString("device_id");

        String orderId = deviceOrderService.getOrderIdByDeviceUnified(eleCode);
        if (orderId != null) {
            chargingOrderService.completeOrder(orderId);
            deviceOrderService.unbindDevice(eleCode);
        }
    }

    // handleOverloadMessage方法 (第151行)
    public void handleOverloadMessage(String message) {
        try {
            JSONObject payload = JSONObject.parseObject(message);
            String eleCode = payload.getString("device_id");
            String status = payload.getString("status");

            log.info("收到设备overload消息: eleCode={}, status={}", eleCode, status);

            if (!"overload".equalsIgnoreCase(status)) {
                return;
            }

            // 获取关联订单 - 使用统一查询方法
            String orderId = deviceOrderService.getOrderIdByDeviceUnified(eleCode);
            if (orderId == null) {
                log.warn("收到overload消息但未找到关联订单: eleCode={}", eleCode);
                return;
            }

            // 构造断电事件请求
            JSONObject request = new JSONObject();
            request.put("order_id", orderId);
            request.put("ele_code", eleCode);
            request.put("reason", "overload");

            // 处理退款
            chargingOrderController.handlePowerOutage(request);

            log.info("处理overload消息完成: eleCode={}, orderId={}", eleCode, orderId);
        } catch (Exception e) {
            log.error("处理overload消息异常", e);
        }
    }

    /**
     * 处理charing消息（充电开始确认）
     * <p>
     * 当设备发送charing消息时，表示已经开始充电，
     * 并返回实际计算的充电时长
     *
     * @param message MQTT消息内容
     */
    public void handleCharingMessage(String message) {
        try {
            JSONObject payload = JSONObject.parseObject(message);
            String eleCode = payload.getString("device_id");
            Integer chargingSeconds = payload.getInteger("charging_seconds");

            log.info("收到设备charing消息: eleCode={}, chargingSeconds={}", eleCode, chargingSeconds);

            // 使用统一查询方法（内存+数据库）
            String orderId = deviceOrderService.getOrderIdByDeviceUnified(eleCode);
            if (orderId == null) {
                log.warn("收到charing消息但未找到关联订单: eleCode={}", eleCode);
                return;
            }
            // 1. 更新订单状态为充电中，并设置开始时间212
            try {
                // 修复：直接更新订单状态为充电中
                OrderEntity order = chargingOrderService.updateOrderStatus2(orderId, OrderStatus.CHARGING.getCode());
                if (order != null) {
                    order.setStartTime(new Date()); // 设置充电开始时间
                    order.setUpdateDate(new java.sql.Date(System.currentTimeMillis()));
                    chargingOrderService.save(order);

                    log.info("订单状态已更新为充电中: orderId={}, startTime={}", orderId, order.getStartTime());
                }
            } catch (Exception e) {
                log.error("更新订单状态失败: orderId={}", orderId, e);
            }

            // 2. 更新订单的计划充电时长232
            try {
                Long orderIdLong = Long.valueOf(orderId);
                chargingOrderService.updatePlannedDuration(orderIdLong, chargingSeconds / 60);
                log.info("更新订单计划充电时长成功: orderId={}, plannedDuration={}分钟", orderId, chargingSeconds / 60);
            } catch (Exception e) {
                log.error("更新订单计划充电时长失败: orderId={}", orderId, e);
            }
        } catch (Exception e) {
            log.error("处理charing消息异常", e);
        }
    }

    /**
     * 处理changed消息（充电器功率变化）
     * <p>
     * 当设备发送changed消息时，表示用户私自更换了更大功率的充电器，
     * 需要停止供电
     *
     * @param message MQTT消息内容
     */
    public void handleChangedMessage(String message) {
        try {
            JSONObject payload = JSONObject.parseObject(message);
            String deviceId = payload.getString("device_id");

            log.info("收到设备changed消息: deviceId={}", deviceId);

            // 获取关联订单 - 使用统一查询方法
            String orderId = deviceOrderService.getOrderIdByDeviceUnified(deviceId);
            if (orderId == null) {
                log.warn("收到changed消息但未找到关联订单: deviceId={}", deviceId);
                return;
            }

            // 构造断电事件请求
            JSONObject request = new JSONObject();
            request.put("order_id", orderId);
            request.put("ele_code", deviceId);
            request.put("reason", "changed");

            // 处理退款
            chargingOrderController.handlePowerOutage(request);

            log.info("处理changed消息完成: deviceId={}, orderId={}", deviceId, orderId);
        } catch (Exception e) {
            log.error("处理changed消息异常", e);
        }
    }

    /**
     * 处理errordone消息（充电插头被拔下）
     */
    public void handleErrorDoneMessage(String message) {
        try {
            JSONObject payload = JSONObject.parseObject(message);
            String deviceId = payload.getString("device_id");
    
            log.info("收到设备errordone消息: deviceId={}", deviceId);
    
            // 获取关联订单 - 使用统一查询方法
            String orderId = deviceOrderService.getOrderIdByDeviceUnified(deviceId);
            if (orderId == null) {
                log.warn("收到errordone消息但未找到关联订单: deviceId={}", deviceId);
                return;
            }
    
            // 构造断电事件请求
            JSONObject request = new JSONObject();
            request.put("id", orderId);
            request.put("ele_code", deviceId);
            request.put("reason", "errordone");
    
            // 处理退款（注意：handlePowerOutage方法已经包含了设备映射清理逻辑）
            chargingOrderController.handlePowerOutage(request);
    
            log.info("处理errordone消息完成: deviceId={}, orderId={}", deviceId, orderId);
        } catch (Exception e) {
            log.error("处理errordone消息异常", e);
        }
    }

    /**
     * 处理done消息（充电完成）
     * <p>
     * 当设备发送done消息时，表示充电时长结束，
     * 需要停止供电并完成订单
     *
     * @param deviceId 电桩号
     */
    public void handleDoneMessage(String deviceId) {
        try {
            // 修复：正确解析设备消息格式 "ICCID.done"
//            String[] parts = message.trim().split("\\.");
//            if (parts.length < 2 || !"done".equals(parts[1])) {
//                log.warn("done消息格式不正确: {}", message);
//                return;
//            }
            
//            String deviceId = parts[0];
//            String status = "done"; // 固定为done状态
//
//            log.info("收到设备done消息: deviceId={}, status={}", deviceId, status);
    
            // 获取关联订单 - 使用统一查询方法321
            String orderId = deviceOrderService.getOrderIdByDeviceUnified(deviceId);
            if (orderId == null) {
                log.warn("收到done消息但未找到关联订单: deviceId={}", deviceId);
                return;
            }
    
            // 构造断电事件请求
            JSONObject request = new JSONObject();
            request.put("id", orderId);
            //request.put("order_id", orderId);
            request.put("ele_code", deviceId);
            request.put("reason", "charging_complete");
    
            // 处理充电完成
            chargingOrderController.handlePowerOutage(request);
    
            log.warn("处理done消息完成: deviceId={}, orderId={}", deviceId, orderId);
        } catch (Exception e) {
            log.error("处理done消息异常", e);
        }
    }

    /**
     * 处理NoLoad消息（无负载检测）
     * <p>
     * 当设备发送NoLoad消息时，表示检测到无负载状态，
     * 需要停止供电并处理退款
     *
     * @param message MQTT消息内容
     */
    public void handleNoLoadMessage(String message) {
        try {
            JSONObject payload = JSONObject.parseObject(message);
            String deviceId = payload.getString("device_id");
            String status = payload.getString("status");

            log.info("收到设备NoLoad消息: deviceId={}, status={}", deviceId, status);

            if (!"no load".equalsIgnoreCase(status)) {
                return;
            }

            // 获取关联订单 - 使用统一查询方法
            String orderId = deviceOrderService.getOrderIdByDeviceUnified(deviceId);
            if (orderId == null) {
                log.warn("收到NoLoad消息但未找到关联订单: deviceId={}", deviceId);
                return;
            }

            // 构造断电事件请求
            JSONObject request = new JSONObject();
            request.put("order_id", orderId);
            request.put("ele_code", deviceId);
            request.put("reason", "no_load");

            // 处理退款
            chargingOrderController.handlePowerOutage(request);

            log.info("处理NoLoad消息完成: deviceId={}, orderId={}", deviceId, orderId);
        } catch (Exception e) {
            log.error("处理NoLoad消息异常", e);
        }
    }
}
